# 剑指 Offer II 064. 神奇的字典
# 设计一个使用单词列表进行初始化的数据结构，单词列表中的单词 互不相同 。 如果给出一个单词，请判定能否只将这个单词中一个字母换成另一个字母，使得所形成的新单词存在于已构建的神奇字典中。

# 实现 MagicDictionary 类：

# MagicDictionary() 初始化对象
# void buildDict(String[] dictionary) 使用字符串数组 dictionary 设定该数据结构，dictionary 中的字符串互不相同
# bool search(String searchWord) 给定一个字符串 searchWord ，判定能否只将字符串中 一个 字母换成另一个字母，使得所形成的新字符串能够与字典中的任一字符串匹配。如果可以，返回 true ；否则，返回 false 。


# 示例：

# 输入
# inputs = ["MagicDictionary", "buildDict", "search", "search", "search", "search"]
# inputs = [[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]]
# 输出
# [null, null, false, true, false, false]

# 解释
# MagicDictionary magicDictionary = new MagicDictionary();
# magicDictionary.buildDict(["hello", "leetcode"]);
# magicDictionary.search("hello"); // 返回 False
# magicDictionary.search("hhllo"); // 将第二个 'h' 替换为 'e' 可以匹配 "hello" ，所以返回 True
# magicDictionary.search("hell"); // 返回 False
# magicDictionary.search("leetcoded"); // 返回 False


# 提示：

# 1 <= dictionary.length <= 100
# 1 <= dictionary[i].length <= 100
# dictionary[i] 仅由小写英文字母组成
# dictionary 中的所有字符串 互不相同
# 1 <= searchWord.length <= 100
# searchWord 仅由小写英文字母组成
# buildDict 仅在 search 之前调用一次
# 最多调用 100 次 search


class MagicDictionary:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.dic = {}

    def buildDict(self, dictionary: List[str]) -> None:
        # 只能换一个字符，那么必定是长度相等的两个字符串才可以
        # 根据字符串长度创建字典，长度相同的字符串写入一个列表
        for word in dictionary:
            if len(word) not in self.dic:
                self.dic[len(word)] = [word]
            else:
                self.dic[len(word)].append(word)

    def search(self, searchWord: str) -> bool:
        if len(searchWord) not in self.dic:
            return False
        word_list = self.dic[len(searchWord)]
        for word in word_list:
            # 对每个相同长度词进行比较进行比较，字符不同的数量超过 1 则不可能符合条件
            wrongtimes = 0
            for i in range(len(word)):
                if word[i] != searchWord[i]:
                    wrongtimes += 1
                if wrongtimes > 1:  # 至少两个字符不相同
                    break
            if wrongtimes == 1:     # 只有一个
                return True

        return False


# Your MagicDictionary object will be instantiated and called as such:
# obj = MagicDictionary()
# obj.buildDict(dictionary)
# param_2 = obj.search(searchWord)
